<?php

namespace app\service\impl;

use app\popo\model\Order;
use app\popo\model\OrderDetail;
use app\popo\model\User;
use app\popo\vo\OrderReportVO;
use app\popo\vo\SalesTop10ReportVO;
use app\popo\vo\TurnoverReportVO;
use app\popo\vo\UserReportVO;
use app\service\ReportService;
use Carbon\Carbon;
use support\Db;

class ReportServiceImpl implements ReportService
{
    /**
     * 统计指定时间区间内的营业额数据
     * @param string $begin 开始日期
     * @param string $end 结束日期
     * @return TurnoverReportVO
     */
    public function getTurnoverStatistics(string $begin, string $end): TurnoverReportVO
    {
        // 当前集合用于存放从begin到end范围内的每天的日期
        $dateList = [];
        $beginDate = Carbon::parse($begin);
        $endDate = Carbon::parse($end);
        
        // 计算日期范围内每一天的日期
        while ($beginDate->lte($endDate)) {
            $dateList[] = $beginDate->format('Y-m-d');
            $beginDate->addDay();
        }
        
        // 存放每天的营业额
        $turnoverList = [];
        foreach ($dateList as $date) {
            // 查询date日期对应的营业额数据，营业额是指状态为"已完成"的订单金额合计
            $turnover = Order::where('order_time', '>=', $date . ' 00:00:00')
                ->where('order_time', '<=', $date . ' 23:59:59')
                ->where('status', 5) // 已完成
                ->sum('amount');
            $turnoverList[] = $turnover ?: 0;
        }
        
        // 封装返回结果
        $turnoverReportVO = new TurnoverReportVO();
        $turnoverReportVO->setDateList(implode(',', $dateList));
        $turnoverReportVO->setTurnoverList(implode(',', $turnoverList));
        
        return $turnoverReportVO;
    }

    /**
     * 统计指定时间区间内的用户数据
     * @param string $begin 开始日期
     * @param string $end 结束日期
     * @return UserReportVO
     */
    public function getUserStatistics(string $begin, string $end): UserReportVO
    {
        // 当前集合用于存放从begin到end范围内的每天的日期
        $dateList = [];
        $beginDate = Carbon::parse($begin);
        $endDate = Carbon::parse($end);
        
        // 计算日期范围内每一天的日期
        while ($beginDate->lte($endDate)) {
            $dateList[] = $beginDate->format('Y-m-d');
            $beginDate->addDay();
        }
        
        // 存放每天的新增用户数量
        $newUserList = [];
        // 存放每天的总用户数量
        $totalUserList = [];
        
        foreach ($dateList as $date) {
            // 新增用户数量
            $newUserCount = User::where('create_time', '>=', $date . ' 00:00:00')
                ->where('create_time', '<=', $date . ' 23:59:59')
                ->count();
            $newUserList[] = $newUserCount;
            
            // 总用户数量
            $totalUserCount = User::where('create_time', '<=', $date . ' 23:59:59')
                ->count();
            $totalUserList[] = $totalUserCount;
        }
        
        // 封装返回结果
        $userReportVO = new UserReportVO();
        $userReportVO->setDateList(implode(',', $dateList));
        $userReportVO->setNewUserList(implode(',', $newUserList));
        $userReportVO->setTotalUserList(implode(',', $totalUserList));
        
        return $userReportVO;
    }

    /**
     * 统计指定时间区间内的订单数据
     * @param string $begin 开始日期
     * @param string $end 结束日期
     * @return OrderReportVO
     */
    public function getOrderStatistics(string $begin, string $end): OrderReportVO
    {
        // 当前集合用于存放从begin到end范围内的每天的日期
        $dateList = [];
        $beginDate = Carbon::parse($begin);
        $endDate = Carbon::parse($end);
        
        // 计算日期范围内每一天的日期
        while ($beginDate->lte($endDate)) {
            $dateList[] = $beginDate->format('Y-m-d');
            $beginDate->addDay();
        }
        
        // 存放每天的订单总数
        $orderCountList = [];
        // 存放每天的有效订单数
        $validOrderCountList = [];
        
        foreach ($dateList as $date) {
            // 总订单数
            $orderCount = Order::where('order_time', '>=', $date . ' 00:00:00')
                ->where('order_time', '<=', $date . ' 23:59:59')
                ->count();
            $orderCountList[] = $orderCount;
            
            // 有效订单数（状态为已完成的订单）
            $validOrderCount = Order::where('order_time', '>=', $date . ' 00:00:00')
                ->where('order_time', '<=', $date . ' 23:59:59')
                ->where('status', 5) // 已完成
                ->count();
            $validOrderCountList[] = $validOrderCount;
        }
        
        // 计算时间区间内的订单总数量
        $totalOrderCount = Order::where('order_time', '>=', $begin . ' 00:00:00')
            ->where('order_time', '<=', $end . ' 23:59:59')
            ->count();
        
        // 计算时间区间内的有效订单数量
        $validOrderCount = Order::where('order_time', '>=', $begin . ' 00:00:00')
            ->where('order_time', '<=', $end . ' 23:59:59')
            ->where('status', 5) // 已完成
            ->count();
        
        // 计算订单完成率
        $orderCompletionRate = $totalOrderCount == 0 ? 0.0 : round($validOrderCount / $totalOrderCount, 2);
        
        // 封装返回结果
        $orderReportVO = new OrderReportVO();
        $orderReportVO->setDateList(implode(',', $dateList));
        $orderReportVO->setOrderCountList(implode(',', $orderCountList));
        $orderReportVO->setValidOrderCountList(implode(',', $validOrderCountList));
        $orderReportVO->setTotalOrderCount($totalOrderCount);
        $orderReportVO->setValidOrderCount($validOrderCount);
        $orderReportVO->setOrderCompletionRate($orderCompletionRate);
        
        return $orderReportVO;
    }

    /**
     * 统计指定时间区间内的销量排名前10
     * @param string $begin 开始日期
     * @param string $end 结束日期
     * @return SalesTop10ReportVO
     */
    public function getSalesTop10(string $begin, string $end): SalesTop10ReportVO
    {
        // 使用模型关联查询，从orders和order_detail表获取数据
        $result = OrderDetail::query()
            ->leftJoin('orders', 'order_detail.order_id', '=', 'orders.id')
            ->where('orders.order_time', '>=', $begin . ' 00:00:00')
            ->where('orders.order_time', '<=', $end . ' 23:59:59')
            ->where('orders.status', 5) // 已完成订单
            ->selectRaw('order_detail.name, sum(order_detail.number) as total_sales')
            ->groupBy('order_detail.name')
            ->orderByDesc('total_sales')
            ->limit(10)
            ->get()
            ->toArray();
        
        // 存放商品名称
        $nameList = [];
        // 存放销量
        $numberList = [];
        
        foreach ($result as $item) {
            $nameList[] = $item['name'];
            $numberList[] = $item['total_sales'];
        }
        
        // 封装返回结果
        $salesTop10ReportVO = new SalesTop10ReportVO();
        $salesTop10ReportVO->setNameList(implode(',', $nameList));
        $salesTop10ReportVO->setNumberList(implode(',', $numberList));
        
        return $salesTop10ReportVO;
    }

    /**
     * 导出运营数据报表
     * @return array 运营数据
     */
    public function exportBusinessData(): array
    {
        // 查询概览数据
        // 时间取最近30天
        $begin = Carbon::now()->subDays(30)->format('Y-m-d');
        $end = Carbon::now()->format('Y-m-d');
        
        // 营业额
        $turnoverStatistics = $this->getTurnoverStatistics($begin, $end);
        
        // 用户统计
        $userStatistics = $this->getUserStatistics($begin, $end);
        
        // 订单统计
        $orderStatistics = $this->getOrderStatistics($begin, $end);
        
        // 销量排名top10
        $salesTop10 = $this->getSalesTop10($begin, $end);
        
        return [
            'dateRange' => $begin . ' 至 ' . $end,
            'turnoverStatistics' => $turnoverStatistics->toArray(),
            'userStatistics' => $userStatistics->toArray(),
            'orderStatistics' => $orderStatistics->toArray(),
            'salesTop10' => $salesTop10->toArray()
        ];
    }
}